home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / netprog.zip / NETPROG.TAR / reliable / rudpserv.c < prev   
C/C++ Source or Header  |  1989-12-17  |  3KB  |  143 lines

  1. /*
  2.  * Example of server using UDP protocol.
  3.  * This server has a run-time option to discard packets and to
  4.  * modify the sequence number, to allow testing of the more
  5.  * reliable client side.
  6.  *
  7.  *    rudpserv [ -e <delay> ] [ -d <percent> ] [ -s <percent> ]
  8.  */
  9.  
  10. #include    "rudp.h"
  11. #include    <netdb.h>
  12.  
  13. int    discardrate = 0;    /* should be [0-100] */
  14. int    delay = 0;        /* delay in responding, seconds */
  15. int    seqmodrate  = 0;    /* should be [0-100] */
  16.  
  17. main(argc, argv)
  18. int    argc;
  19. char    *argv[];
  20. {
  21.     int            sockfd;
  22.     char            *s;
  23.     struct sockaddr_in    serv_addr;
  24.     struct servent        *sp;
  25.  
  26.     pname = argv[0];
  27.     while (--argc > 0 && (*++argv)[0] == '-')
  28.         for (s = argv[0]+1; *s != '\0'; s++)
  29.             switch (*s) {
  30.  
  31.             case 'd':    /* next arg is discard rate */
  32.                 if (--argc <=0)
  33.                    err_quit("-d requires another argument");
  34.                 discardrate = atoi(*++argv);
  35.                 break;
  36.  
  37.             case 'e':    /* next arg is delay in seconds */
  38.                 if (--argc <=0)
  39.                    err_quit("-e requires another argument");
  40.                 delay = atoi(*++argv);
  41.                 break;
  42.  
  43.             case 's':    /* next arg is sequence mod rate */
  44.                 if (--argc <=0)
  45.                    err_quit("-s requires another argument");
  46.                 seqmodrate = atoi(*++argv);
  47.                 break;
  48.  
  49.             default:
  50.                 err_quit("illegal option %c", *s);
  51.             }
  52.  
  53.     /*
  54.      * Open a UDP socket (an Internet datagram socket).
  55.      */
  56.  
  57.     if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  58.         err_dump("server: can't open datagram socket");
  59.  
  60.     /*
  61.      * Find out what port we should be listening on, then bind
  62.      * our local address so that the client can send to us.
  63.      */
  64.  
  65.     if ( (sp = getservbyname(MYECHO_SERVICE, "udp")) == NULL)
  66.         err_quit("server: unknown service: %s/udp", MYECHO_SERVICE);
  67.  
  68.     bzero((char *) &serv_addr, sizeof(serv_addr));
  69.     serv_addr.sin_family      = AF_INET;
  70.     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  71.     serv_addr.sin_port        = sp->s_port;
  72.  
  73.     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
  74.         err_dump("server: can't bind local address");
  75.  
  76.     echo(sockfd);        /* do it all */
  77.         /* NOTREACHED */
  78. }
  79.  
  80. /*
  81.  * Read the contents of the socket and write each line back to
  82.  * the sender.
  83.  */
  84.  
  85. echo(sockfd)
  86. int    sockfd;
  87. {
  88.     int            n, clilen;
  89.     long            percent, random(), time();
  90.     char            line[MAXLINE];
  91.     struct sockaddr_in    cli_addr;
  92.  
  93.     if (discardrate || seqmodrate)    /* init random number sequence */
  94.         srandom( (int) time((long *) 0) );
  95.  
  96.     for ( ; ; ) {
  97.         /*
  98.          * Read a message from the socket and send it back
  99.          * to whomever sent it.
  100.          */
  101.  
  102. ignore:
  103.         clilen = sizeof(cli_addr);
  104.         n = recvfrom(sockfd, line, MAXLINE, 0,
  105.                 (struct sockaddr *) &cli_addr, &clilen);
  106.         if (n < 0)
  107.             err_dump("server: recvfrom error");
  108.  
  109.         /*
  110.          * First see if we should delay before doing anything.
  111.          */
  112.  
  113.         if (delay)
  114.             sleep(delay);
  115.  
  116.         /*
  117.          * See if we should discard this packet.
  118.          */
  119.  
  120.         if (discardrate) {
  121.             percent = (random() % 100) + 1;        /* [1, 100] */
  122.             if (percent <= discardrate)
  123.                 goto ignore;
  124.         }
  125.  
  126.         /*
  127.          * See if we should modify the sequence number of
  128.          * this packet.
  129.          */
  130.  
  131.         if (seqmodrate) {
  132.             percent = (random() % 100) + 1;        /* [1, 100] */
  133.             if (percent <= seqmodrate)
  134.                 line[percent & 3]++;
  135.                 /* change one of line[0], [1], [2] or [3] */
  136.         }
  137.  
  138.         if (sendto(sockfd, line, n, 0, (struct sockaddr *)
  139.                 &cli_addr, clilen) != n)
  140.             err_dump("server: sendto error");
  141.     }
  142. }
  143.